<template>
  <div class="response">
    <!-- 响应tab -->
    <el-tabs v-model="activeName" @tab-click="handleClick">
      <el-tab-pane label="响应体" name="responseBody" style="position: relative;">
        <div :style="{ position: 'absolute', 'z-index': imageSrc ? 1000 : -1 }">
          <el-switch v-model="isImage" class="ml-2" inline-prompt style="
              --el-switch-on-color: #13ce66;
              --el-switch-off-color: #ff4949;
              margin-right: 10px;
            " active-text="图片" inactive-text="文本" @change="changeSwitch" />
          <el-button size="small" @click="downloadImg">下载</el-button>
        </div>
        <div :style="{
          top: imageSrc ? '36px' : '0',
          'z-index': (language != 'image' || !isImage) ? 1000 : -1
        }" style="
          position: absolute;
          bottom: 20px;
          width: 100%;">
          <header>
            <el-select v-model="language" size="small" style="width: 70px; margin-right: 10px"
              @change="(val) => changeLanguage(val)">
              <el-option v-for="item in languageList" :key="item" :label="item" :value="item" />
            </el-select>
            <el-select v-model="code" size="small" style="width: 100px" @change="(val) => changeCode(val)">
              <el-option v-for="item in codeList" :key="item" :label="item" :value="item" />
            </el-select>
            <el-button @click="formatFn" size="small" :icon="Brush"
              style="float: right; margin-right: 10px">格式化</el-button>
          </header>
          <Editor :readonly="true" height="calc(100% - 50px)" :modelValue="responseContent" ref="responseBodyEditor"
            :language="language" />
        </div>
        <img :src="imageSrc" alt="" srcset="" width="200px" height="200px"
          :style="{ 'z-index': imageSrc && language == 'image' ? 1000 : -1 }"
          style="display: block;position: absolute;top:36px;" />
      </el-tab-pane>
      <el-tab-pane :label="`响应头 ${data.responseHeaders ? `(${data.responseHeaders.length})` : `(0)`}`"
        name="responseHeader">
        <el-table :data="data.responseHeaders" highlight-current-row style="width: 100%; height: 100%"
          :key="rendertable">
          <el-table-column type="index" width="50" />
          <el-table-column property="name" label="名称" />
          <el-table-column property="value" label="值" />
        </el-table>
      </el-tab-pane>
      <el-tab-pane :label="`控制台 ${data.extractorResponse ? `(${data.extractorResponse.length})` : `(0)`}`"
        name="responseVar">
        <ul class="response-ul" v-if="data.extractorResponse && data.extractorResponse.length">
          <li v-for="(item, index) of data.extractorResponse" :key="index"><el-tag type="info" size="small"
              class="mr-5px">操作</el-tag>{{ item }}</li>
        </ul>
        <el-empty :image-size="50" description="暂无数据" v-else />
      </el-tab-pane>
      <el-tab-pane :label="`断言结果 ${data.assertInfos ? `(${data.assertInfos.length})` : `(0)`}`"
        name="responseAssertion">
        <ul class="response-ul" v-if="data.assertInfos && data.assertInfos.length">
          <li v-for="(item, index) of data.assertInfos" :key="index"><small class="mr-5px">{{ index + 1
              }}.</small><el-tag :type="item.assertResult == '失败' ? 'danger' : 'success'" size="small" class="mr-5px">{{
                item.assertResult
              }}</el-tag>{{ item.name }} | {{ item.assertInfoDetail }}
          </li>
        </ul>
        <el-empty :image-size="50" description="暂无数据" v-else />
      </el-tab-pane>
      <el-tab-pane label="实际请求" name="request">
        <div class="content">
          <template v-if="data.responseResult?.requestUrl">
            <h4 class="h4">请求URL:</h4>
            <span class="url">{{ data.responseResult?.requestUrl }}</span>
          </template>
          <template v-if="data.requestHeaderList?.length">
            <h4 class="h4">Header:</h4>
            <el-table :data="data.requestHeaderList" highlight-current-row style="width: 100%" :key="rendertable">
              <el-table-column type="index" width="50" />
              <el-table-column property="keyName" label="名称" />
              <el-table-column property="keyValue" label="值" />
            </el-table>
          </template>
          <template v-if="data.requestParamsList?.length">
            <h4 class="h4">Params:</h4>
            <el-table :data="data.requestParamsList" style="width: 100%" :key="rendertable">
              <el-table-column type="index" width="50" />
              <el-table-column prop="keyName" label="名称" />
              <el-table-column prop="keyValue" label="值" />
            </el-table>
          </template>
          <template v-if="data.requestBody">
            <h4 class="h4">Body:</h4>
            <pre>{{ data.requestBody }}</pre>
          </template>
          <el-empty :image-size="50" description="暂无数据" v-if="
            !data.responseResult?.requestUrl &&
            !data.requestHeaderList?.length &&
            !data.requestParamsList?.length &&
            !data.requestBody
          " />
        </div>
      </el-tab-pane>
    </el-tabs>
    <div class="result" :style="{
      color: changeColor(data.responseResult?.responseCode, data.responseResult?.responseResult)
    }">
      <span class="result-text" :style="{
        background:
          changeColor(data.responseResult?.responseCode, data.responseResult?.responseResult) +
          '22'
      }">{{ data.responseResult?.responseResult }}</span>
      <span class="result-status">{{ data.responseResult?.responseCode }}</span>
      <span class="result-time" v-if="data.responseResult?.responseTime">{{ data.responseResult?.responseTime
      }}ms</span>
      <span class="result-size" v-if="data.responseResult?.responseSize">{{ data.responseResult?.responseSize }}B</span>
    </div>
  </div>
</template>

<script setup lang="ts">
import { Brush } from '@element-plus/icons-vue'
import Editor from './Editor.vue'
import { propTypes } from '@/utils/propTypes'
const activeName = ref('responseBody')
const rendertable = ref(false)
const language = ref('json')
const languageList = ref(['json', 'xml', 'html', 'text'])
const code = ref('UTF-8')
const codeList = ref(['UTF-8', 'UTF-16', 'GBK', 'GB2312', 'ISO-8859-1', 'ASCII'])
const responseBodyEditor = ref()
const imageSrc = ref()
const isImage = ref(false)
const props = defineProps({
  data: propTypes.object.def({})
})
const responseContent = ref('')
watch(
  () => props.data,
  () => {
    init()
    responseContent.value = props.data.responseContent
  },
  {
    deep: true
  }
)
/** json和图片格式切换 */
const changeSwitch = (val) => {
  responseContent.value = ''
  responseContent.value = props.data.responseContent
  if (!val) {
    language.value = 'text'
    changeLanguage('text')
  } else {
    language.value = 'image'
  }
}
/** 页签切换 */
const handleClick = () => { }
/** 下载图片 */
const downloadImg = () => {
  const link = document.createElement('a')
  link.style.display = 'none'
  link.download = 'response.png'
  link.href = imageSrc.value
  document.body.appendChild(link)
  link.click()
  document.body.removeChild(link)
}
/** 初始化响应颜色、内容类型 */
const init = () => {
  language.value = ''
  imageSrc.value = ''
  isImage.value = false
  changeColor(props.data.responseResult?.responseCode, props.data.responseResult?.responseResult)
  language.value = props.data.responseResult?.responseContentType
  if (language.value != 'image') {
    isImage.value = false
    changeLanguage(language.value)
  } else {
    isImage.value = true
    imageSrc.value = props.data.imageUrl
  }
  rendertable.value = !rendertable.value
}

/** 格式化 */
const formatFn = () => {
  responseBodyEditor.value.formatFn()
}
/** 内容类型改变处理 */
const changeLanguage = (val) => {
  responseBodyEditor.value.handleLanguageChange(val)
}
/** 编码改变处理 */
const changeCode = (val) => {
  responseBodyEditor.value.handleCharsetChange(val)
}
/** 响应结果颜色判断 */
const changeColor = (code, result) => {
  if (code >= 200 && code < 300) {
    return '#00c261'
  } else if (code >= 300 && code < 400) {
    return '#536ae3'
  } else if (code >= 400 && code < 500) {
    return '#e6e22a'
  } else if (code >= 500) {
    return '#ea1c24'
  }
  if (!code && result) {
    return result == '成功' ? '#00c261' : '#ea1c24'
  }
}
onMounted(() => {
  if (JSON.stringify(props.data) != '{}') {
    init()
  }
})
</script>

<style scoped lang="scss">
:deep(.el-select--small .el-select__wrapper) {
  box-shadow: none;
}

:deep(.el-tabs__header) {
  padding: 10px 0 0;
}

:deep(.el-tabs__nav-wrap::after) {
  height: 1px;
}

.border-1 {
  border-color: #f5f5f5;
  border-radius: 5px;
}

.url {
  font-size: 14px;
  color: #344054;
}

.content {
  height: 100%;
  padding-bottom: 20px;
  overflow: auto;
  box-sizing: border-box;
}

h4 {
  font-size: 14px;
  font-weight: 500;
}

.response-ul {
  height: 100%;
  padding: 0;
  margin: 0;
  overflow: auto;
  font-size: 14px;
  list-style: none;

  li {
    display: flex;
    padding: 10px 0;
    border-bottom: 1px solid var(--el-border-color-light);
    align-items: center;
  }
}

.result {
  position: absolute;
  top: 10px;
  right: 10px;
  display: flex;
  width: 200px;
  height: 40px;
  font-size: 12px;
  justify-content: space-between;
  align-items: center;
}
</style>
